using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace TelnetTests
{
    [TestFixture]
    public class EncryptionNullTests : TestsBase
    {
        public EncryptionNullTests()
        {
            TestsBase.EnsureConsoleTraceListener();
        }

        protected override TelnetExpect.TelnetStream Create_Testee(System.IO.Stream conn)
        {
            TelnetExpect.TelnetStream dut = new TelnetExpect.TelnetStream(conn);
            dut.AddOptionHandler(new TelnetExpect.EncryptionNullTelnetHandler());
            return dut;
        }

        static readonly TelnetExpect.TelnetOption[] ExpectedLocalOptions
            = new TelnetExpect.TelnetOption[] { TelnetExpect.TelnetOption.EncryptionOption };

        static readonly byte[] ExpectedResponses_WillAndIsIsNull = {
                IAC, WILL, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    0, // IS
                    0, // NULL
                    IAC,SE,
            };

        static readonly byte[] ExpectedResponses_Will = {
                IAC, WILL, OptionCode.EncryptionOption,
            };

        static readonly byte[] ExpectedResponses_IsIsNull = {
                //IAC, WILL, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    0, // IS
                    0, // NULL
                    IAC,SE,
            };

        [Test]
        public void RcvSupport_EmptyList()
        {
            byte[] inputEmpty = {
                IAC, DO, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    1, // SUPPORT
                    IAC,SE,
            };
            DoTest(inputEmpty, ExpectedResponsesNone, ExpectedResponses_WillAndIsIsNull,
                null,
                ExpectedLocalOptions, null);
        }

        [Test]
        public void RcvSupport_Some()
        {
            byte[] inputSome = {
                IAC, DO, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    1, // SUPPORT
                    1, 2, 3, 4, // type 1-4
                    IAC,SE,
            };
            DoTest(inputSome, ExpectedResponsesNone, ExpectedResponses_WillAndIsIsNull,
                null,
                ExpectedLocalOptions, null);
        }

        [Test]
        [Category("Causes Debug.Assert")]
        public void Rcv_Odd_SupportSubNegWithoutWill()
        {
            byte[] inputSome = {
                //IAC, DO, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    1, // SUPPORT
                    1, 2, 3, 4, // type 1-4
                    IAC,SE,
            };
            DoTest(inputSome, ExpectedResponsesNone, ExpectedResponses_IsIsNull,
                null,
                new TelnetExpect.TelnetOption[] { }, null);
        }

        [Test]
        public void Rcv_Bad_Short()
        {
            byte[] inputSome = {
                IAC, DO, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    IAC,SE,
            };
            DoTest(inputSome, ExpectedResponsesNone, ExpectedResponses_Will,
                null,
                ExpectedLocalOptions, null);
        }

        [Test]
        public void Rcv_Bad_OtherSubCode()
        {
            byte[] inputSome = {
                IAC, DO, OptionCode.EncryptionOption,
                //----
                IAC,SB,
                    OptionCode.EncryptionOption,
                    99,
                    IAC,SE,
            };
            DoTest(inputSome, ExpectedResponsesNone, ExpectedResponses_Will,
                null,
                ExpectedLocalOptions, null);
        }

    }
}
